package com.tarena.lbs.attach.service.impl;

import com.tarena.lbs.attach.dao.mapper.AttachMapper;
import com.tarena.lbs.attach.pojo.po.AttachPO;
import com.tarena.lbs.attach.pojo.param.UploadParam;
import com.tarena.lbs.attach.pojo.vo.FileVO;
import com.tarena.lbs.attach.service.AttachService;
import com.tarena.lbs.attach.utils.FileUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class AttachServiceImpl implements AttachService {
    // 从YML配置文件注入：文件本地存储根路径（如 d:/files/）
    @Value("D://home/images/dev/lbs_attach/") // 从配置文件获取存储根路径
    private String basePath;
    // 从YML配置文件注入：文件访问URL前缀（如 http://localhost:9081/api/attach/files/）
    @Value("http://localhost:19999/admin/attach/") // 从配置文件获取访问URL前缀
    private String accessPath;

    @Resource
    private AttachMapper attachMapper;

    /**
     * 上传文件并保存记录
     * @param file 上传的文件
     * @param businessType 业务类型（如1=商家Logo）
     * @param businessId 关联的业务ID（如门店ID）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileVO upload(MultipartFile file, Integer businessType, Integer businessId) throws Exception {
        // 1. 校验文件非空
        if (file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }
        // 1. 生成文件UUID（唯一标识）
        String fileUuid = UUID.randomUUID().toString().replace("-", "");

        // 2. 按日期生成存储目录（如 basePath/2025/11/11/）
        String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
        String storePath = basePath + dateDir + "/"; // 完整存储目录

        // 3. 调用工具类保存文件，返回文件名（含后缀）
        String fileName = FileUtil.makeTempFile(file, storePath, fileUuid);

        // 4. 解析文件基础信息（从MultipartFile中获取）
        String originalFileName = file.getOriginalFilename(); // 前端上传的原始文件名（如 "头像.jpg"）
        long contentLength = file.getSize(); // 文件大小（单位：字节）
        String contentType = file.getContentType(); // 文件类型（MIME类型，如 image/jpeg、application/pdf）

        // 5. 若为图片文件，获取宽高（非图片则为0）
        int width = 0, height = 0;
        if (contentType != null && contentType.startsWith("image/")) {
            // 构建图片文件对象（磁盘上的实际文件）
            File imageFile = new File(storePath + fileName);
            // 用ImageIO读取图片宽高
            BufferedImage image = ImageIO.read(imageFile);
            width = image.getWidth();
            height = image.getHeight();
        }

        // 6. 构建attach表对应的实体类，封装所有元数据
        AttachPO attachPO = new AttachPO();
        attachPO.setFileUuid(fileUuid); // 文件唯一标识（UUID）
        attachPO.setClientFileName(originalFileName); // 原始文件名
        attachPO.setContentLength(contentLength); // 文件大小
        attachPO.setDownloadTimes(0); // 下载次数默认为0

        // 将MIME类型映射为整数代码
//        String contentTypeInt = mapContentTypeToInt(contentType);
        attachPO.setContentType(contentType); // 文件类型

        attachPO.setWidth(width); // 图片宽度（非图片为0）
        attachPO.setHeight(height); // 图片高度（非图片为0）
        attachPO.setBusinessType(businessType == null ? 0 : businessType); // 业务类型（如2=门店图片）
        attachPO.setBusinessId(businessId == null ? 0 : businessId); // 关联业务ID（如门店ID=101）
        attachPO.setIsCover(0); // 默认不是封面图（前端可通过参数修改）
        attachPO.setGmtModified(System.currentTimeMillis()); // 补充更新时间（原有缺失）
        attachPO.setModifiedUserId(1L); // 补充更新人ID（原有缺失）
        attachPO.setStatus(0); // 状态：0=正常（可用）
        attachPO.setGmtCreate(System.currentTimeMillis()); // 创建时间（毫秒时间戳）
        attachPO.setCreateUserId(1L); // 临时：创建人ID（实际应从登录态获取，如当前登录用户ID）
        attachPO.setModifiedUserName("admin"); // 补充更新人姓名（原有缺失）
        attachPO.setCreateUserName("admin"); // 临时：创建人姓名（实际从登录态获取）

        // 7. 保存到数据库
        //依赖 AttachMapper.xml 中的 insert SQL，
        // 插入后 attachPO.id 会自动获取数据库自增主键（因为 Mapper 配置了 useGeneratedKeys="true"）。
        attachMapper.insert(attachPO);

        // 8. 构建返回给前端的VO对象（隐藏数据库无关字段，只返回前端需要的信息）
        FileVO fileVO = new FileVO();
        BeanUtils.copyProperties(attachPO, fileVO); // 复制PO的属性到VO（如id、fileUuid、clientFileName）
        // 拼接文件访问URL：accessPath（http://xxx/files/） + dateDir（2025/11/11/） + fileName（uuid123.jpg）
        fileVO.setUrl(accessPath + dateDir + "/" + fileName);

        // 打印上传成功日志
        log.info("文件上传成功：{}，存储路径：{}", originalFileName, storePath + fileName);
        return fileVO;
    }

    /**
     * 删除文件（磁盘文件+数据库记录）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    /*功能：同步删除磁盘上的文件和数据库中的记录，确保数据一致性。*/
    public boolean delete(Integer id) {
        // 1. 根据文件ID查询attach表记录（先确认记录存在）
        /*前置校验：避免删除不存在的记录，减少无效操作。*/
        AttachPO attachPO = attachMapper.selectById(id);
        if (attachPO == null) {
            log.warn("文件记录不存在：{}", id);
            return false;
        }

        // 2. 从数据库记录中解析日期目录（根据创建时间）
        String dateDir = new SimpleDateFormat("yyyy/MM/dd")
                .format(new Date(attachPO.getGmtCreate()));
        // 重建文件名：UUID + 原始文件后缀（与上传时的文件名规则一致）
        String fileName = attachPO.getFileUuid() + attachPO.getClientFileName().substring(
                attachPO.getClientFileName().indexOf("."));
        // 拼接完整磁盘路径：basePath + dateDir + fileName → d:/files/2025/11/11/uuid123.jpg
        String fullPath = basePath + dateDir + "/" + fileName;

        // 3. 调用工具类删除磁盘文件
        FileUtil.deleteFile(List.of(fullPath));

        // 4. 删除数据库记录
        int rows = attachMapper.deleteById(id);
        log.info("文件删除成功：ID={}，路径={}", id, fullPath);
        return rows > 0;
    }

    /**
     * 将MIME类型映射为整数代码
     * @param contentType MIME类型字符串
     * @return 对应的整数代码
     */
//    private Integer mapContentTypeToInt(String contentType) {
//        if (contentType == null) {
//            return 0; // 未知类型
//        }
//
//        switch (contentType) {
//            case "image/jpeg":
//            case "image/jpg":
//                return 1;
//            case "image/png":
//                return 2;
//            case "image/gif":
//                return 3;
//            case "image/webp":
//                return 4;
//            case "application/pdf":
//                return 5;
//            case "text/plain":
//                return 6;
//            case "application/msword":
//                return 7;
//            case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
//                return 8;
//            default:
//                return 0; // 未知类型
//        }
//    }
}